package com.feige.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feige.constant.Constants;
import com.feige.dao.CourseMapper;
import com.feige.pojo.Course;
import com.feige.pojo.User;
import com.feige.pojo.UserCourse;
import com.feige.pojo.vo.CourseVo;
import com.feige.service.CourseService;
import com.feige.service.UserCourseService;
import com.feige.utils.aliyun.AliyunOssHandler;
import com.feige.utils.inventcode.ShareCodeUtil;
import com.feige.utils.qrcode.QrCodeUtils;
import com.feige.utils.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程表 服务实现类
 * </p>
 *
 * @author feige
 * @since 2020-11-20
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Resource
    private CourseMapper courseMapper;


    @Resource
    private UserCourseService userCourseService;

    @Autowired
    private RedisUtils redisUtils;


    @Override
    public List<CourseVo> getMyAttendCourse(long pageNum, long pageSize, String userId) {
        Map<String, Object> map = new HashMap<>(10);
        map.put("pageNum",(pageNum - 1) * pageSize);
        map.put("pageSize",pageSize);
        map.put("userId",userId);
        return courseMapper.getMyAttendCourse(map);
    }

    @Override
    public long getMyAttendCourseCount(String userId) {
        return courseMapper.getMyAttendCourseCount(userId);
    }

    @Transactional(rollbackFor = { Exception.class })
    @Override
    public boolean deleteCourseById(String id) {
        //先删除user和course的中间表user_course中course_id等于当前课程的的数据
        UpdateWrapper<UserCourse> wrapper = new UpdateWrapper<>();
        wrapper.eq("course_id",id);
        boolean remove = userCourseService.remove(wrapper);
        boolean b = this.removeById(id);
        return remove && b;
    }

    @Override
    public boolean createCourse(Course course) {
        String fileName = IdUtil.simpleUUID() + ".jpg";
        String name = AliyunOssHandler.joinFileName(QrCodeUtils.COURSE_FILE_TYPE_NAME, fileName);
        String inventQrCodePath = AliyunOssHandler.BUCKET_URL + name;
        course.setInventQrCodePath(inventQrCodePath);
        boolean save = this.save(course);
        boolean b = QrCodeUtils.generateQrCodeSaveOss(Constants.COURSE_QR_CODE_URL_PREFIX + course.getId(), name);
        return save && b;
    }

    @Override
    public CourseVo getCourseVoById(String id) {
        return courseMapper.getCourseVoById(id);
    }

    @Override
    public int incrementJoinCount(String courseId) {
        return courseMapper.incrementJoinCount(courseId);
    }

    @Override
    public int decrementJoinCount(String courseId) {
        return courseMapper.decrementJoinCount(courseId);
    }

    @Override
    public CourseVo getCourseVoByInvestCode(String investCode) {
        return courseMapper.getCourseVoByInvestCode(ShareCodeUtil.codeToId(investCode));
    }

    @Override
    public User getUserByCourseId(String courseId) {
        return courseMapper.getUserByCourseId(courseId);
    }

    @Override
    public Course getById(Serializable id) {
        String key = Constants.COURSE_KEY + id;
        Course course = (Course)redisUtils.get(key);
        if (ObjectUtil.isNotNull(course)){
            return course;
        }else {
            course = super.getById(id);
            if (ObjectUtil.isNotNull(course)){
                course.setInventCode(ShareCodeUtil.toSerialCode(course.getInventCode()));
                // 设置随机过期时间
                int randomInt = RandomUtil.randomInt(1,10);
                redisUtils.set(key,course,randomInt * 2 * 60 * 60);
                return course;
            }else {
                return null;
            }
        }
    }
}
